var SVG_NS = "http://www.w3.org/2000/svg"

/**
 * 保存
 */
function save() {
	registry.collectModelPosition()
}
class Registry {
	constructor(arg) {
		this.points = new Map();
	}

	update(name, x, y) {
		this.points.set(name, x, y);
	}

	get(name) {
		return this.points.get(name);
	}

	points() {
		return this.points.values();
	}

	submit() {
		let data = this.collectModelPosition();

	}

	collectModelPosition() {
		let map = new Map();
		let gs = document.getElementsByTagNameNS(SVG_NS, "g")
		for (var i = 0; i < gs.length; i++) {
			let g = gs[i]
			let transform = g.getAttribute("transform")
			let transformStr = transform.substring(transform.indexOf("(") + 1, transform.indexOf(")"))
			let ns = transformStr.split(",");
			let x = parseInt(ns[0])
			let y = parseInt(ns[1])
			let tableName = g.getAttribute("tableName")
			let table = ts.get(tableName);
			let meta = {
				x: x,
				y: y,
				meta: table
			}
			map.set(tableName, meta)
		}
		return map;
	}
}

/**
 * 表模型头部
 */
class TabelModelHeader {
	constructor(tableName, comment) {
		this.element = document.createElement("div")
		this.element.setAttribute("class", "tablename")
		this.element.innerHTML = tableName + "<br/>" + comment;
	}
	toElement() {
		return this.element;
	}
}

/**
 * 表模型字段主体
 */
class TableModelColumns {
	constructor(columns) {
		if (!columns) throw "TableModelColumns.constructor：无效的参数"
		this.element = document.createElement("div")
		this.element.setAttribute("class", "columns")
		let columnDoc = this.makeList(columns)
		this.element.appendChild(columnDoc)
	}
	makeList(columns) {
		let ul = document.createElement("ul")
		for (var i = 0; i < columns.length; i++) {
			if (i > 10) {
				//continue;
			}
			let column = columns[i]
			let li = document.createElement("li")
			li.innerHTML = (column.primaryKey ? "🔑" : "") + " " + column.columnName + "  -  " + column
				.columnComment;
			ul.appendChild(li);
		}
		return ul;
	}
	toElement() {
		return this.element;
	}
}
class TableModel {
	constructor(tableStruct) {
		this.model = document.createElement("div")
		this.model.setAttribute("class", "model")
		let h = new TabelModelHeader(tableStruct.tableName, tableStruct.tableComment);
		let cs = new TableModelColumns(tableStruct.columns);
		this.appendChild(h)
		this.appendChild(cs)
	}
	appendChild(object) {
		this.model.appendChild(object.toElement())
	}

	clientHeight() {
		return this.model.clientHeight;
	}

	toElement() {
		return this.model;
	}
}

/**
 * 线段对象。参考SVG polyline
 * http://www.voidme.com/svg/svg-polyline
 */
class Polyline {
	/**
	 * @param {Object} x
	 * @param {Object} y 
	 * @param {Object} s 线的起始点
	 */
	constructor(x, y, s) {
		this.polyline = document.createElementNS(SVG_NS, 'polyline')
		this.points = new Points(x, y);
		this.startX = x;
		this.startY = y;
		this.turningPointX = x; //转折点X
		this.turningPointY = y; //转折点Y
		//this.polyline.setAttribute('points', this.points.toString())
		this.polyline.setAttribute("marker-end", "url(#markerArrow)")
		this.polyline.setAttribute("style", "fill:none;stroke:#000;stroke-width:2");
		let self = this;
		//侦听事件
		this.polyline.addEventListener('onmouseover', function(evt) {
			self.polyline.setAttribute("style", "fill:none;stroke:#000;stroke-width:3")
		})
		// this.startConnectPoint=null;
		// this.endConnectPoint=null;
	}

	getStartConnectPoint() {
		return this.startConnectPoint;
	}

	getEndConnectPoint() {
		return this.endConnectPoint;
	}

	/**
	 * 连接起点
	 * @param {Object} connectPoint 起点对象
	 */
	connectStartPoint(connectPoint) {
		this.startConnectPoint = connectPoint;
		this.startCPX = connectPoint.x;
		this.startCPY = connectPoint.y;
		console.log("起点坐标：" + this.startCPX + "," + this.startCPY)
		//植入跟踪器
		this.startConnectPoint.addTracker((x, y) => {
			console.log("起点跟踪器检测到线段的起点发生移动")
			//改变线段轨迹
			this.reMove();
		})
	}

	/**
	 * 连接终点
	 * @param {Object} connectPoint终点对象
	 */
	connectEndPoint(connectPoint) {
		this.endConnectPoint = connectPoint;
		this.endCPX = connectPoint.x;
		this.endCPY = connectPoint.y;
		console.log("起点坐标：" + this.startCPX + "," + this.startCPY)
		console.log("终点坐标：" + this.endCPX + "," + this.endCPY)
	}

	toElement() {
		return this.polyline;
	}
	move(x, y) {
		//移动过程判断用户是否有转向意图，如果有，则配合用户转向（通过Y的位置偏移来判断是否转向）
		this.points.add(x, y);
		this.polyline.setAttribute('points', this.points.getPath())
	}

	/**
	 * 连接线的头部发生位移，将重新设置线段的路径
	 */
	reMove() {
		let sx = this.startConnectPoint.x;
		let sy = this.startConnectPoint.y;
		let ex = this.endConnectPoint.x;
		let ey = this.endConnectPoint.y;
		console.log("最新位置：",sx, sy, ex, ey)

		//重新构造线段
		this.polyline.setAttribute('points', this._build(sx, sy, ex, ey))
	}
	_build(sx, sy, ex, ey) {
		return sx + "," + sy + " " + ex + "," + ey;
	}
	/**
	 * 连接线的尾部发生位移，将重新设置线段的路径
	 */
	endMove() {

	}

	destroy() {
		document.removeChild(this.polyline.toElement())
	}
}

class Points {
	constructor(x, y) {
		this.firstX = x;
		this.firstY = y;
		this.array = [
			[x, y]
		];
	}

	add(x, y) {
		this.array.push([x, y]);
	}

	lastX() {
		return this.array[this.array.length - 1][0];
	}

	lastY() {
		return this.array[this.array.length - 1][1];
	}

	firstPoint() {
		return this.firstX + "," + this.firstY;
	}

	lastPoint() {
		return this.lastX() + "," + this.lastY();
	}

	getPath() {
		return this.firstPoint() + " " + this.lastPoint();
	}

	beautify() {
		var xs = [];
		var ys = [];
		for (var i = 0; i < this.array.length; i++) {
			let points = this.array[i];
			xs.push(points[0]);
			ys.push(points[1]);
		}
		var tx = xs[0];
		var txs = [];
		var ty = ys[0];
		var tys = [];
		//公差范围小于5的归为一类，取平均值
		let c = 20;
		for (let index = 0; index < xs.length; index++) {
			let x = xs[index];
			if (Math.abs(x - tx) < c) {
				txs.push(tx);
			} else {
				tx = x;
				txs.push(tx);
			}

			let y = ys[index];
			if (Math.abs(y - ty) < c) {
				tys.push(ty);
			} else {
				ty = y;
				tys.push(ty);
			}
		}
		let pointArray = [];
		for (let index = 0; index < tys.length; index++) {
			pointArray.push([txs[index], tys[index]]);
		}
		this.array = pointArray
	}

	toString() {
		//美化线条
		this.beautify();
		let string = "";
		for (var i = 0; i < this.array.length; i++) {
			let point = this.array[i];
			if (i > 0) {
				string += " "
			}
			string += point[0] + "," + point[1];
		}
		return string;
	}
}

/**
 * HTML容器，在svg中嵌入HTML时使用
 */
class ForeignObject {
	constructor(arg) {
		this.foreignObject = document.createElementNS(SVG_NS, "foreignObject")
		this.foreignObject.setAttribute("class", "node")
		this.foreignObject.setAttribute("x", 0)
		this.foreignObject.setAttribute("y", 0)
		this.foreignObject.setAttribute("width", "200px")
		// this.foreignObject.setAttribute("height", "300px")
	}

	toElement() {
		return this.foreignObject;
	}

	getTableModel() {
		return this.tableModel;
	}

	setHeight(height) {
		this.foreignObject.getAttribute("height", height + "px");
	}

	appendChild(object) {
		if (typeof(object) != "object") throw "子元素类型不正确"
		this.tableModel = object;
		this.foreignObject.appendChild(this.tableModel.toElement())
	}
}

/**
 * 连接点组
 */
class ConnectPointGroup {

	/**
	 * 连接点父节点的坐标，这里是指表模型的坐标
	 * @param {Object} x
	 * @param {Object} y
	 */
	constructor(x, y, h) {
		this.h = h;
		this.make(x, y, h)
	}

	hide() {
		this.top.hide();
		this.bottom.hide();
		this.left.hide();
		this.right.hide();
	}
	show() {
		this.top.show();
		this.bottom.show();
		this.left.show();
		this.right.show();
	}
	make(x, y, h) {
		let cpl = this.connectPointLocation(x, y, h)
		this.top = new ConnectPoint(cpl.top.x, cpl.top.y)
		this.bottom = new ConnectPoint(cpl.bottom.x, cpl.bottom.y)
		this.right = new ConnectPoint(cpl.right.x, cpl.right.y)
		this.left = new ConnectPoint(cpl.left.x, cpl.left.y)
	}

	install() {
		this.installSvg(this.top.toElement())
		this.installSvg(this.bottom.toElement())
		this.installSvg(this.right.toElement())
		this.installSvg(this.left.toElement())
	}
	installSvg(el){
		svg.appendChild(el)
		makeLine(el);
	}

	move(x, y) {
		let cpl = this.connectPointLocation(x, y)
		this.top.move(cpl.top.x, cpl.top.y)
		this.bottom.move(cpl.bottom.x, cpl.bottom.y)
		this.right.move(cpl.right.x, cpl.right.y)
		this.left.move(cpl.left.x, cpl.left.y)
	}

	connectPointLocation(x, y) {
		let top = {
			x: x + 100,
			y: y
		};
		let bottom = {
			x: x + 100,
			y: y + (this.h)
		};
		let right = {
			x: x,
			y: y + (this.h / 2)
		};
		let left = {
			x: x + 200,
			y: y + (this.h / 2)
		};
		return {
			top: top,
			bottom: bottom,
			left: left,
			right: right
		};
	}
}

// class Connect {
// 	constructor(polyline, type) {
// 		this.type = type;
// 		this.polyline = polyline;
// 	}

// 	type() {
// 		return this.type;
// 	}

// 	polyline() {
// 		return this.polyline;
// 	}
// }
/**
 * 连接点
 */
class ConnectPoint {
	constructor(cx, cy) {
		//<circle cx="400" cy="220" r="5" stroke="black" stroke-width="1" fill="fff" />
		this.el = document.createElementNS(SVG_NS, "circle")
		this.x = cx;
		this.y = cy;
		this.el.setAttribute("cx", cx)
		this.el.setAttribute("cy", cy)
		this.el.setAttribute("stroke", "black")
		this.el.setAttribute("stroke-width", "1")
		this.el.setAttribute("fill", "#fff")
		this.el.setAttribute("r", "4")
		this.el.setAttribute("id","asfff------")
		window.connectPoints.push(this);
		this.callbacks = [];
		//注册鼠标悬浮事件
		this.el.addEventListener("mouseover", function() {
			console.log('文本鼠标悬停测试：');
		});

	}

	x() {
		return this.el.getAttribute("cx");
	}
	y() {
		return this.el.getAttribute("cy");
	}

	hide() {
		this.el.setAttribute("r", "4")
	}
	show() {
		this.el.setAttribute("r", "4")
	}

	addTracker(callback) {
		if (typeof(callback) == "function") {
			this.callbacks.push(callback)
		}
	}

	move(x, y) {
		console.log("连接点位置：",x,y)
		this.el.setAttribute("cx", x)
		this.el.setAttribute("cy", y)
		//通知连接线开始改变路径
		for (var i = 0; i < this.callbacks.length; i++) {
			let callback = this.callbacks[i];
			callback(x, y)
		};
	}

	toElement() {
		return this.el;
	}
}
